package com.iplant.basic.serviceImpl.dao.cfg;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.utils.cache.CacheUtils;
import com.iplant.basic.service.po.fmc.FMCShift;
import com.iplant.basic.service.po.fmc.FMCStation;
import com.iplant.basic.service.po.fmc.FMCWorkArea;
import com.iplant.basic.service.po.fmc.FMCWorkshop;
import com.iplant.basic.serviceImpl.FMCServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.cfg.CFGCalendar;

public class CFGCalendarDAO extends BaseDAO {

    private static Logger logger = LoggerFactory.getLogger(CFGCalendarDAO.class);

    private static CFGCalendarDAO Instance = null;

    private CFGCalendarDAO() {
        super(CFGCalendar.class);
    }

    public static CFGCalendarDAO getInstance() {
        if (Instance == null)
            Instance = new CFGCalendarDAO();
        return Instance;
    }


    public List<CFGCalendar> CFG_QueryHoliday(BMSEmployee wLoginUser, int wFactoryID, int wWorkshopID,int wWorkAreaID,int wStationID,
                                              int wYear, int wMonth, int wIsCreate, Pagination wPagination, OutResult<Integer> wErrorCode) {

        List<CFGCalendar> wResults = CFG_QueryHoliday(wLoginUser, wFactoryID, wWorkshopID,wWorkAreaID, wStationID,wYear, wMonth, wPagination, wErrorCode);
        try {
            if (wIsCreate == 0)
                return wResults;
            if (wErrorCode.Result != 0)
                return wResults;


            Calendar wMaxCalendar = CalendarTool.getCalendar(wYear, wMonth, 1);
            wMaxCalendar.add(Calendar.MONTH, 1);
            wMaxCalendar.add(Calendar.DAY_OF_MONTH, -1);

            Calendar wMaxSourceCalendar = CalendarTool.getCalendar(wYear, wMonth, 1);

            if (wResults != null && wResults.size() > 0) {
                 //如果时间跨度与天数相等 直接返回
                if( wResults.size()>=wMaxCalendar.get(Calendar.DAY_OF_MONTH)){
                    return wResults;
                }
            }
            CFGCalendar wCFGCalendar;
            if (wMaxSourceCalendar.compareTo(wMaxCalendar) <= 0) {
                wResults = this.CFG_CreateHoliday(wLoginUser, wResults, wFactoryID, wWorkshopID, wWorkAreaID, wStationID, wMaxSourceCalendar, wMaxCalendar, wErrorCode);
            }
        }catch (Exception e){
            wErrorCode.Result=ExceptionTypes.Exception.getValue();
            logger.error("CFG_QueryHoliday",e);
        }
        return wResults;
    }

    public List<CFGCalendar> CFG_QueryHoliday(BMSEmployee wLoginUser, int wFactoryID, int wWorkshopID,int wWorkAreaID,int wStationID,
                                              int wYear, int wMonth, Pagination wPagination, OutResult<Integer> wErrorCode) {

        Map<String, Object> wParams = new HashMap<>();
        wParams.put("FactoryID", wFactoryID);
        wParams.put("WorkshopID", wWorkshopID);
        wParams.put("WorkAreaID", wWorkAreaID);
        wParams.put("StationID", wStationID);
        wParams.put("Year", wYear);
        wParams.put("Month", wMonth);
        return SelectPOList(wLoginUser, wParams, CFGCalendar.class, wPagination, wErrorCode);
    }



    private List<CFGCalendar> CFG_CreateHoliday(BMSEmployee wLoginUser,  List<CFGCalendar> wSourceResults ,  int wFactoryID, int wWorkshopID,int wWorkAreaID,
                                                int wStationID, Calendar wMaxSourceCalendar , Calendar wMaxCalendar, OutResult<Integer> wErrorCode){

        List<CFGCalendar> wResults=new ArrayList<>();

        Map<String, CFGCalendar> wEntityMap=wSourceResults.stream().collect(Collectors.toMap(p->StringUtils.parseCalendarToString( p.CurrentDay,"yyyy-MM-dd"),p->p,(o1,o2)->o1.Active==1?o1:o2));

        CFGCalendar wCFGCalendar;


        ServiceResult<List<FMCShift>> wServiceResult = FMCServiceImpl.getInstance().FMC_QueryShiftList(wLoginUser,
                wFactoryID, wWorkshopID, wWorkAreaID, wStationID, Pagination.getNewMaxSize());
        if (StringUtils.isNotEmpty(wServiceResult.FaultCode)) {
            wErrorCode.Result= ExceptionTypes.Logic.getValue();
            return wResults;
        }
        List<Integer> wShiftList = new ArrayList<>();

        if(wServiceResult.Result!=null&&wServiceResult.Result.size()>0){
            wShiftList=wServiceResult.Result.stream().filter(p->p.Active==1).map(p->p.ShiftType).collect(Collectors.toList());
        }
        //查询时间段内上级记录
        //查询时间段内上上级记录
        Map<String, CFGCalendar> wFactoryMap=new HashMap<>();
        Map<String, CFGCalendar> wWorkshopMap=new HashMap<>();
        Map<String, CFGCalendar> wWorkAreaMap=new HashMap<>();
        if(wStationID>0){
            if(wWorkAreaID<=0){
                FMCStation wFMCStation = CacheUtils.GetCacheInfo(FMCStation.class, wStationID, "");

                if (wFMCStation == null || wFMCStation.ID <= 0) {
                    return wResults;
                }
                wFactoryID = wFMCStation.FactoryID;
                wWorkshopID = wFMCStation.WorkshopID;
                wWorkAreaID = wFMCStation.WorkAreaID;
            }
            List<CFGCalendar> wCFGCalendarList=this.CFG_QueryHoliday(wLoginUser, wFactoryID, wWorkshopID,
                    wWorkAreaID, 0,wMaxSourceCalendar, wMaxCalendar, Pagination.getNewMaxSize(), wErrorCode);
            wWorkAreaMap=wCFGCalendarList.stream().collect(Collectors.toMap(p->StringUtils.parseCalendarToString( p.CurrentDay,"yyyy-MM-dd"),p->p,(o1,o2)->o1.Active==1?o1:o2));
        }
        if(wWorkAreaID>0){
            if(wWorkAreaID<=0){
                FMCWorkArea wFMCWorkArea = CacheUtils.GetCacheInfo(FMCWorkArea.class, wWorkAreaID, "");

                if (wFMCWorkArea == null || wFMCWorkArea.ID <= 0) {
                    return wResults;
                }
                wFactoryID = wFMCWorkArea.FactoryID;
                wWorkshopID = wFMCWorkArea.WorkshopID;
            }
            List<CFGCalendar> wCFGCalendarList=this.CFG_QueryHoliday(wLoginUser, wFactoryID, wWorkshopID,0, 0,wMaxSourceCalendar, wMaxCalendar, Pagination.getNewMaxSize(), wErrorCode);
            wWorkshopMap=wCFGCalendarList.stream().collect(Collectors.toMap(p->StringUtils.parseCalendarToString( p.CurrentDay,"yyyy-MM-dd"),p->p,(o1,o2)->o1.Active==1?o1:o2));

        }
        if(wWorkshopID>0){
            if(wFactoryID<=0){
                FMCWorkshop wFMCWorkshop = CacheUtils.GetCacheInfo(FMCWorkshop.class, wWorkshopID, "");

                if (wFMCWorkshop == null || wFMCWorkshop.ID <= 0) {
                    return wResults;
                }
                wFactoryID = wFMCWorkshop.FactoryID;
            }
            List<CFGCalendar> wCFGCalendarList=this.CFG_QueryHoliday(wLoginUser, wFactoryID, 0,0, 0,wMaxSourceCalendar, wMaxCalendar, Pagination.getNewMaxSize(), wErrorCode);
            wFactoryMap=wCFGCalendarList.stream().collect(Collectors.toMap(p->StringUtils.parseCalendarToString( p.CurrentDay,"yyyy-MM-dd"),p->p,(o1,o2)->o1.Active==1?o1:o2));
        }

        String wDateString="";
        while (wMaxSourceCalendar.compareTo(wMaxCalendar) <= 0) {
            wCFGCalendar = new CFGCalendar();
            wCFGCalendar.CurrentDay = CalendarTool.CloneDate(wMaxSourceCalendar);
            wCFGCalendar.IsHoliday = 0;

            wDateString=StringUtils.parseCalendarToString( wCFGCalendar.CurrentDay,"yyyy-MM-dd");
            if(wEntityMap.containsKey(wDateString)){
                wMaxSourceCalendar.add(Calendar.DAY_OF_MONTH, 1);
                wResults.add(wEntityMap.get(wDateString));
                continue;
            }

            if(wWorkAreaMap.containsKey(wDateString)){
                wCFGCalendar.IsHoliday = wWorkAreaMap.get(wDateString).IsHoliday;
            }else if(wWorkshopMap.containsKey(wDateString)){
                wCFGCalendar.IsHoliday = wWorkshopMap.get(wDateString).IsHoliday;
            }else if(wFactoryMap.containsKey(wDateString)){
                wCFGCalendar.IsHoliday = wFactoryMap.get(wDateString).IsHoliday;
            }

            wCFGCalendar.Year = wCFGCalendar.CurrentDay.get(Calendar.YEAR);
            wCFGCalendar.Month = wCFGCalendar.CurrentDay.get(Calendar.MONTH);
            wCFGCalendar.WorkshopID = wWorkshopID;
            wCFGCalendar.FactoryID = wFactoryID;
            wCFGCalendar.WorkAreaID = wWorkAreaID;
            wCFGCalendar.StationID = wStationID;
            wCFGCalendar.ShiftList=wShiftList;
            wMaxSourceCalendar.add(Calendar.DAY_OF_MONTH, 1);
            //工厂或者车间会直接存储数据库 但是工区与工位不直接存储，只有修改存储功能
            if(wCFGCalendar.WorkAreaID<=0&& wCFGCalendar.StationID<=0&& wCFGCalendar.WorkshopID<=0)
                CFGCalendarDAO.getInstance().UpdatePo(wLoginUser, wCFGCalendar, wErrorCode);

            wResults.add(wCFGCalendar);
            if(wErrorCode.Result!=0)
                return wResults;
        }
        return wResults;
    }

    public List<CFGCalendar> CFG_QueryHoliday(BMSEmployee wLoginUser, int wFactoryID, int wWorkshopID,int wWorkAreaID,int wStationID,
                                              Calendar wStartDate, Calendar wEndDate, int wIsCreate, Pagination wPagination, OutResult<Integer> wErrorCode) {
        List<CFGCalendar> wResults = CFG_QueryHoliday(wLoginUser, wFactoryID, wWorkshopID,wWorkAreaID,wStationID, wStartDate, wEndDate, wPagination, wErrorCode);
        try {
            if (wIsCreate == 0)
                return wResults;
            if (wErrorCode.Result != 0)
                return wResults;


            Calendar wMaxCalendar = CalendarTool.CloneDate(wEndDate);

            Calendar wMaxSourceCalendar = CalendarTool.CloneDate(wStartDate);

            if (wResults != null && wResults.size() > 0) {

               if(wResults.size()>= (CalendarTool.SubDate(wMaxCalendar,wMaxSourceCalendar)+1)){
                   return wResults;
               }
            }
            CFGCalendar wCFGCalendar;
            if (wMaxSourceCalendar.compareTo(wMaxCalendar) <= 0) {
                wResults = this.CFG_CreateHoliday(wLoginUser, wResults, wFactoryID, wWorkshopID, wWorkAreaID, wStationID, wMaxSourceCalendar, wMaxCalendar, wErrorCode);
            }
        }catch (Exception e){
            wErrorCode.Result=ExceptionTypes.Exception.getValue();
            logger.error("CFG_QueryHoliday",e);
        }
        return wResults;
    }


    public List<CFGCalendar> CFG_QueryHoliday(BMSEmployee wLoginUser, int wFactoryID, int wWorkshopID,int wWorkAreaID,int wStationID,
                                              Calendar wStartDate, Calendar wEndDate, Pagination wPagination, OutResult<Integer> wErrorCode) {
        Map<String, Object> wParams = new HashMap<>();
        wParams.put("FactoryID", wFactoryID);
        wParams.put("WorkAreaID", wWorkAreaID);
        wParams.put("StationID", wStationID);
        wParams.put("WorkshopID", wWorkshopID);
        wParams.put("StartDate", wStartDate);
        wParams.put("EndDate", wEndDate);
        return SelectPOList(wLoginUser, wParams, CFGCalendar.class, wPagination, wErrorCode);

    }


}
